from marajo.appengine.api.users import User
from resources.ticket import Ticket
from resources.comment import Comment

from datetime import datetime
import marajo
import boto

import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

from tempfile import NamedTemporaryFile
import xlwt
from threading import Thread
class ReportBuilder(Thread):
    """
    Build this report and email it to a user
    """

    def __init__(self, start_date, end_date, user, email):
        """
        Create a new report based on start_date and 
        end_date
        """
        self.start_date = start_date
        self.end_date = end_date
        self.user = user
        if isinstance(email, list):
            self.email = ",".join(email)
        else:
            self.email = email
        Thread.__init__(self)

    def send_report(self, workbook):
        """Send the report to the email address provided"""
        smtp_host = marajo.conf.get('Notification', 'smtp_host', 'localhost')
        smtp_user = marajo.conf.get('Notification', 'smtp_user', '')
        smtp_pass = marajo.conf.get('Notification', 'smtp_pass', '')
        smtp_from = marajo.conf.get("Notification", "smtp_from", "")
        tmpfl = NamedTemporaryFile()
        workbook.save(tmpfl.name)
        msg = MIMEMultipart()
        msg['From'] = smtp_from
        msg['To'] = self.email
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = "Vermouth Work Report - %s %s" % (self.user.nickname, self.start_date.strftime("%m/%d/%y"))
        msg.attach( MIMEText("Attatched is the report from %s to %s for %s" % (self.start_date.strftime("%m/%d/%y"), self.end_date.strftime("%m/%d/%y"),self.user.nickname) ) )

        part = MIMEBase('application', "octet-stream")
        part.set_payload( tmpfl.read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s Work Report %s to %s.xls"' % (self.user.nickname, self.start_date.strftime("%m/%d/%y"), self.end_date.strftime("%m/%d/%y")))
        msg.attach(part)

        server = smtplib.SMTP(smtp_host)
        server.login(smtp_user, smtp_pass)
        server.sendmail(smtp_from, msg['To'], msg.as_string())
        server.quit()
        tmpfl.close()

    def run(self):
        boto.log.info( "Starting Report for %s" % self.user.nickname)
        boto.log.info( "Start Date: %s" % self.start_date)
        boto.log.info( "End Date: %s" % self.end_date)
        boto.log.info( "Email to: %s" % self.email)

        w = xlwt.Workbook()
        header_font = xlwt.Font()
        header_font.name = 'Times New Roman'
        header_font.bold = True

        header_borders = xlwt.Borders()
        header_borders.bottom = 2

        header_style = xlwt.XFStyle()
        header_style.font = header_font
        header_style.borders = header_borders

        totals_style = xlwt.XFStyle()
        totals_style.font = header_font
        totals_style.borders = xlwt.Borders()
        totals_style.borders.top = 2

        Comment._manager.domain.connection = boto.connect_sdb()
        query = Comment.find()
        query.filter("minutes != ", 0)
        query.filter("owner =", self.user)

        if self.start_date:
            query.filter("date >", self.start_date)
        if self.end_date:
            query.filter("date <", self.end_date)
        vals = self.comment_report(query)
        vals['user'] = self.user
        vals['start_date'] = self.start_date
        vals['end_date'] = self.end_date

        projects = vals['projects']
        for project in projects.values():
            sheet = w.add_sheet(project['project'].name)
            # Header Row
            sheet.write(0,0, "Date", header_style)
            sheet.col(0).width = 0x1200

            sheet.write(0,1, "Employee", header_style)
            sheet.col(1).width = 0x1200

            sheet.write(0,2, "Component", header_style)
            sheet.col(2).width = 0x1200

            sheet.write(0,3, "Type", header_style)
            sheet.col(3).width = 0x4000

            sheet.write(0,4, "Details", header_style)
            sheet.col(4).width = 0x1200

            sheet.write(0,5, "Hours", header_style)
            sheet.col(5).width = 0x0600

            sheet.write(0,6, "Clients", header_style)
            sheet.col(6).width = 0x0600

            row = 0
            for comment in project['comments']:
                row += 1
                sheet.write(row, 0, comment.date.strftime("%d %b %Y"))
                sheet.write(row, 1, str(comment.owner.nickname))
                sheet.write(row, 2, str(comment.ticket.component))
                sheet.write(row, 3, str(comment.ticket.name))
                sheet.write(row, 4, str(comment.ticket.type))
                sheet.write(row, 5, float(comment.minutes)/60)
                sheet.write(row, 6, ",".join([c.name for c in comment.ticket.clients]))
            row += 1
            sheet.write(row, 3, "Total", totals_style)
            sheet.write(row, 4, float(project['minutes'])/60, totals_style)

        # Add the summary report
        sheet = w.add_sheet("Summary - %s" % self.user.nickname)
        row = 0
        sheet.write(0,0, "Project", header_style)
        sheet.col(0).width = 0x4000
        sheet.write(0,1, "Hours", header_style)
        sheet.col(1).width = 0x0600

        for project in projects.values():
            row += 1
            sheet.write(row, 0, project['project'].name)
            sheet.write(row, 1, float(project['minutes'])/60)
        row += 1
        sheet.write(row, 0, "Total", totals_style)
        sheet.write(row, 1, float(vals['total_minutes'])/60, totals_style)
        self.send_report(w)

    def comment_report(self, query):
        """Base for comment reports"""
        from resources.ticket import Ticket
        total_minutes = 0
        total_cost = 0
        projects = {}
        comments = []
        clients = {}
        for comment in query:
            total_minutes += comment.minutes
            comment.ticket = Ticket.get_by_id(comment.ticket.id)
            if not projects.has_key(comment.ticket.project.id):
                projects[comment.ticket.project.id] = {
                    "project": comment.ticket.project,
                    "minutes": 0,
                    "comments": []
                }
            for client in comment.ticket.clients:
                if not clients.has_key(client.id):
                    clients[client.id] = {
                        'name': client.name,
                        'minutes': 0,
                    }

                clients[client.id]['minutes'] += comment.minutes
            projects[comment.ticket.project.id]['minutes'] += comment.minutes
            projects[comment.ticket.project.id]['comments'].append(comment)
            comments.append(comment)
        vals = {}
        vals['comments'] = comments
        vals['clients'] = clients
        vals['projects'] = projects
        vals['total_minutes'] = total_minutes
        return vals

